<?php

class users extends base {

    private $content;
    private $jscode = <<<JSCODE
<script type="text/javascript" src="templates/sand/javascripts/smoothie.js"></script>
<script type="text/javascript">

var rate_dl;
var rate_ul;
var ping;
var onload=false;
var dseries1 = new TimeSeries();
var dseries2 = new TimeSeries();
var dseries21 = new TimeSeries();

window.setInterval(function(){
// Request class
HTMLRequest = function(){
	Request = window.XMLHttpRequest?new XMLHttpRequest():window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):false;
        if(!Request)
		alert("Error initializing XMLHttpRequest!");
	Request.fn = function(fn){
		if(typeof fn=='string')return new Function(fn);
		if(typeof fn=='function')return fn;
		if(typeof fn=='undefined')return new Function();
	};
	Request.config = {
		'xml' : false,
		'404' : 'File not found'
	};
 
	Request.success = false;
	Request.loading = false;
	Request.error = false;
        Request.async = false;
 
	Request.submit = function(obj){
		if(Request){
			Request.onreadystatechange = function(){
				if(Request.readyState==4){
                                                if((Request.status==200)||(Request.status==0)){
						Response = Request.config['xml']?Request.responseXml:Request.responseText;
						if(Request.success){
							Request.fn(Request.success).call(this, Response, Request);
						} else {
							Request.fn(obj.success).call(this, Response, Request);
						}
					} else {
						if(Request.success){
							Request.fn(Request.loading).call(this, Request);
						} else {
							Request.fn(obj.loading).call(this, Request);
						}
					}
				} else {
					if(Request.success){
						Request.fn(Request.error).call(this, Request.config['404']);
					} else {
						Request.fn(obj.error).call(this, Request.config['404']);
					}
				};
			}
			Request.open("GET", obj.url, true);
			Request.send(null);
		} else obj.error.call(this, Request);
	};

	return Request;
};

// Eval code
var req = new HTMLRequest;
req.submit({
	url : 'index.php?page=users&submenu=Realtime&action=query_client&param1=%interface%&param2=%pingip%',
	xml : false,
	success : function(res, req){
                var parts=res.split("|");
		document.getElementById('download_rate').innerHTML = parts[0];
		document.getElementById('ping').innerHTML = parts[1];
                var pings=parts[1].split("/");
                window.ping=pings[4];
                rate=parts[0];
                var rates=rate.split("/");
                window.rate_ul=rates[0];
                window.rate_dl=rates[1];
                console.log('HTTP Result: '+res+' = rate:'+parts[0]+' ; ping:'+parts[1]);
	},
	loading : function(){ console.log('loading ...'); },
	error : function(err){ console.log(err); }
});
req1=null;

function createTimeline1() {
    var chart1 = new SmoothieChart();
    chart1.addTimeSeries(dseries1, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 4 });
    chart1.streamTo(document.getElementById("ping_chart"), 500);
}

function createTimeline2() {
    var chart2 = new SmoothieChart();
    chart2.addTimeSeries(dseries2, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 4 });
    chart2.addTimeSeries(dseries21, { strokeStyle: 'rgba(255, 0, 0, 1)', fillStyle: 'rgba(255, 0, 0, 0.5)', lineWidth: 4 });
    chart2.streamTo(document.getElementById("traffic_chart"), 500);
}

dseries1.append(new Date().getTime(), window.ping);
dseries2.append(new Date().getTime(), window.rate_ul);
dseries21.append(new Date().getTime(), window.rate_dl);

if (!onload) {
    createTimeline1();
    createTimeline2();
    onload=true;
}

}, 3000);

</script>
JSCODE;

    public function submenu() {
        $this->submenu = array();
        $this->submenu[0]["name"] = "Active";
        $this->submenu[0]["callback"] = "active";
        $this->submenu[0]["icon"] = "icons/tick.png";
        $this->submenu[0]["rights"] = 0;
        $this->submenu[0]["enabled"] = true;
        $this->submenu[1]["name"] = "Shaper";
        $this->submenu[1]["callback"] = "shaper";
        $this->submenu[1]["icon"] = "icons/excl.gif";
        $this->submenu[1]["rights"] = 0;
        $this->submenu[1]["enabled"] = true;
        $this->submenu[2]["name"] = "Realtime";
        $this->submenu[2]["callback"] = "realtime";
        $this->submenu[2]["icon"] = "icons/bomb.gif";
        $this->submenu[2]["rights"] = 0;
        $this->submenu[2]["enabled"] = true;
        $this->submenu[3]["name"] = "Radius";
        $this->submenu[3]["callback"] = "radius";
        $this->submenu[3]["rights"] = 0;
        $this->submenu[3]["icon"] = "icons/application_edit.png";
        $this->submenu[3]["enabled"] = true;
        $this->submenu[4]["name"] = "Bandwidth monitor";
        $this->submenu[4]["callback"] = "bandwidth";
        $this->submenu[4]["rights"] = 0;
        $this->submenu[4]["icon"] = "icons/stats.gif";
        $this->submenu[4]["enabled"] = true;
        $this->_submenu($this->submenu);
    }

    public function run() {
        $this->submenu();
        $callback = $this->_run();
        if ($callback)
            $this->content = $this->$callback();
        $this->finish($this->content);
    }

    private function cut_array($buffer, $separator) {
        $buffera = explode("\n", $buffer);
        $cleaned = array();
        $sep_active = false;
        foreach ($buffera as $ba) {
            if ($sep_active && strstr($ba, "|"))
                $cleaned[] = $ba;
            if (strstr($ba, $separator))
                $sep_active = true;
        }
        return $cleaned;
    }

    private function show($param1) {
        $sessions = $this->sessions_to_array();
        foreach ($sessions as $session) {
            if ($session[0] == $param1) {
                $output = "<h1>{$session[1]}</h1><br />\n";
                $output.="Interface: <strong>{$session[0]}</strong><br />\n";
                $output.="Calling SID: <strong>{$session[2]}</strong><br />\n";
                $output.="IP: <strong>{$session[3]}</strong><br />\n";
                $output.="Rate limit: <strong>{$session[4]}</strong><br />\n";
                $output.="Type: <strong>{$session[5]}</strong><br />\n";
                $output.="Comp: <strong>{$session[6]}</strong><br />\n";
                $output.="State: <strong>{$session[7]}</strong><br />\n";
                $output.="Uptime: <strong>{$session[8]}</strong><br />\n";
                $output.="<br />\n";
                $output.="<a href='index.php?page=users&submenu=Active&action=terminate&param1={$session[0]}'><img src='templates/sand/images/error.png' /></a> <strong>Terminate connection</strong><br />\n";
            }
        }
        return $output;
    }

    private function sessions_to_array($href_link = false) {
        $sessions = file_get_contents("dumps/sessions");

        if (empty($sessions))
            return array(array("Session file is empty!"));

        $sessionsa = $this->cut_array($sessions, "-----");
        $url = $_SERVER['REQUEST_URI'];
        foreach ($sessionsa as $sa) {
            $sa = str_replace(" ", "", $sa);
            $sa = str_replace("\r", "", $sa);
            $columns = explode("|", $sa);
            if ($href_link)
                $columns[0] = "<a href='{$url}&{$href_link}&param1={$columns[0]}&param2={$columns[3]}'>{$columns[0]}</a>";
            $session_array[] = $columns;
        }
        return $session_array;
    }

    private function terminate($param1) {
        exec("/var/www/scripts/accel-terminate-user.sh {$param1}");
        $out = "{$param1} terminated!";
        return $out;
    }

    public function allview($param1, $param2) {
        $all_logged_in = $this->sessions_to_array("action=show");
        $match = false;
        foreach ($all_logged_in as $loggedin) {
            $int = $loggedin[0];
            $user = $loggedin[1];
            $mac = $loggedin[2];
            $ip = $loggedin[3];
            $all_array = array($int, $user, $mac, $ip);
            if (in_array($param1, $all_array) || in_array($param2, $all_array))
                $match = $loggedin;
        }
        if (!$match)
            return "No user found on criteria: {$param1} {$param2}<br>\n";

        $match[0] = strip_tags($match[0]);
        $interface = $match[0];

        $file = "/var/run/radattr.{$interface}";
        $radattr = file_get_contents($file);
        $radattr = str_replace("\n", "<br>\n", $radattr);


        $info = "<h1>{$match[1]}</h1><br />\n";
        $info.="Interface: <strong>{$interface}</strong><br />\n";
        $info.="Calling SID: <strong>{$match[2]}</strong><br />\n";
        $info.="IP: <strong>{$match[3]}</strong><br />\n";
        $info.="Rate limit: <strong>{$match[4]}</strong><br />\n";
        $info.="Type: <strong>{$match[5]}</strong><br />\n";
        $info.="Comp: <strong>{$match[6]}</strong><br />\n";
        $info.="State: <strong>{$match[7]}</strong><br />\n";
        $info.="Uptime: <strong>{$match[8]}</strong><br />\n";
        $info.="<br />\n";

        $realtime .= "<h1>{$interface} [{$match[3]}]</h1><br /><br />";
        $realtime .= "<canvas id=\"traffic_chart\" width=\"500\" height=\"150\"></canvas><br>\n";
        $realtime .= "Traffic (DL/UL KBps): <div id='download_rate'>/</div><br><br />\n";
        $realtime .= "<canvas id=\"ping_chart\" width=\"500\" height=\"150\"></canvas><br>\n";
        $realtime .= "Ping (ms): <div id='ping'>/</div><br>\n";
        $jscode = $this->jscode;
        $jscode = str_replace("%pingip%", $match[3], $jscode);
        $jscode = str_replace("%interface%", $interface, $jscode);

        $commands.="<a href='index.php?page=users&submenu=Active&action=terminate&param1={$match[0]}'><img src='templates/sand/images/error.png' /></a> <strong>Terminate connection</strong><br />\n";
        $commands.="<br />\n";
        $table="
        {$jscode}
        <table>
        <tr>
        <td width=50% valign=top>{$info}
        <strong>Radius:</strong><br>
        {$radattr}
        </td>
        <td>
        {$realtime}
        </td>
        </td>
        <td></td>
        </tr>    
        </table>
        {$commands}";
        //return $info . "<strong>Radius:</strong><br>\n" . $radattr . "<br>\n" . $jscode . $realtime . $commands;
        return $table;
    }

    public function active() {
        $action = $_REQUEST["action"];
        $param1 = $_REQUEST["param1"];
        $param2 = $_REQUEST["param2"];
        switch ($action) {
            case "show":
                $out = $this->show($param1);
                return $out;
                break;
            case "terminate":
                $out = $this->terminate($param1);
                return $out;
                break;
            case "allview":
                $out = $this->allview($param1, $param2);
                return $out;
                break;
            default:
        }
        $table = $this->sessions_to_array("action=show");
        $header[] = array("interface", "username", "calling id", "remote ip", "rate limit", "type", "comp", "state", "uptime");
        $table_html = rows2table(array_merge($header, $table), true);
        return $table_html;
    }

    private function shaper_view($param1) {
        $sessions = $this->sessions_to_array();
        foreach ($sessions as $session) {
            if ($session[0] == $param1) {
                $current_session = $session;
            }
        }
        $int = $current_session[0];
        $rate = $current_session[4];
        //exec("/sbin/tc -s -d class show dev {$int}", $shaper_class);
        exec("/sbin/tc qdisc show dev {$int} && tc filter show dev {$int} parent ffff:", $shaper_class);
        foreach ($shaper_class as $sc) {
            $sc_all.=$sc . "<br>\n";
        }
        $content = <<<CONTENT
        <h1>{$int}</h1>
        <br>
        Assigned Rate: {$rate}<br /><br />
        {$sc_all}<br />
CONTENT;
        return $content;
    }

    public function shaper() {
        $action = $_REQUEST["action"];
        $param1 = $_REQUEST["param1"];
        $param2 = $_REQUEST["param2"];
        switch ($action) {
            case "view":
                $out = $this->shaper_view($param1);
                return $out;
                break;
            default:
        }
        $table = $this->sessions_to_array("action=view");
        $header[] = array("interface", "username", "calling id", "remote ip", "rate limit", "type", "comp", "state", "uptime");
        $table_html = rows2table(array_merge($header, $table), true);
        return $table_html;
    }

    private function realtime_view($param1, $param2) {
        $output .= "<h1>{$param1} [{$param2}]</h1><br /><br />";
        $output .= "<canvas id=\"traffic_chart\" width=\"500\" height=\"150\"></canvas><br>\n";
        $output .= "Traffic (DL/UL KBps): <div id='download_rate'>/</div><br><br />\n";
        $output .= "<canvas id=\"ping_chart\" width=\"500\" height=\"150\"></canvas><br>\n";
        $output .= "Ping (ms): <div id='ping'>/</div><br>\n";
        $jscode = $this->jscode;
        $jscode = str_replace("%pingip%", $param2, $jscode);
        $jscode = str_replace("%interface%", $param1, $jscode);
        return $jscode . $output;
    }

    private function query_client($param1, $param2) {
        $r_traffic1 = exec("/sbin/ifconfig ppp0 | grep bytes");   //RX bytes:17964 (17.9 KB) TX bytes:17946 (17.9 KB)
        $r_traffic1 = str_replace("    ", " ", $r_traffic1);
        $r_traffic1 = str_replace("   ", " ", $r_traffic1);
        $r_traffic1 = str_replace("  ", " ", $r_traffic1);
        sleep(1);
        $r_traffic2 = exec("/sbin/ifconfig ppp0 | grep bytes");
        $r_traffic2 = str_replace("    ", " ", $r_traffic2);
        $r_traffic2 = str_replace("   ", " ", $r_traffic2);
        $r_traffic2 = str_replace("  ", " ", $r_traffic2);
        $rx1 = explode(" ", $r_traffic1);
        $rx1 = explode(":", $rx1[2]);
        $rx1 = (int) $rx1[1];
        $tx1 = explode(" ", $r_traffic1);
        $tx1 = explode(":", $tx1[6]);
        $tx1 = (int) $tx1[1];
        $rx2 = explode(" ", $r_traffic2);
        $rx2 = explode(":", $rx2[2]);
        $rx2 = (int) $rx2[1];
        $tx2 = explode(" ", $r_traffic2);
        $tx2 = explode(":", $tx2[6]);
        $tx2 = (int) $tx2[1];
        $rxrate = (($rx2 - $rx1) * 8) / 1000;
        $txrate = (($tx2 - $tx1) * 8) / 1000;
        $r_ping = exec("/bin/ping {$param2} -c1 -w1", $rt_lines, $return);   //rtt min/avg/max/mdev = 0.246/0.246/0.246/0.000 ms
        //$txrate=rand(1,100);$rxrate=rand(1,100);$r_ping=rand(1,100);
        die($rxrate . "/" . $txrate . "|" . $r_ping);
    }

    public function realtime() {
        $action = $_REQUEST["action"];
        $param1 = $_REQUEST["param1"];
        $param2 = $_REQUEST["param2"];
        switch ($action) {
            case "query_client":
                $out = $this->query_client($param1, $param2);
                return $out;
                break;
            case "realtime_view":
                $out = $this->realtime_view($param1, $param2);
                return $out;
                break;
            default:
        }
        //exec ("cd /var/www/graphs && php /var/www/graphs/update.php");
        $table = $this->sessions_to_array("action=realtime_view");
        $header[] = array("interface", "username", "calling id", "remote ip", "rate limit", "type", "comp", "state", "uptime");
        $table_html = rows2table(array_merge($header, $table), true);
        return $table_html;
    }

    private function radius_view($param1, $param2) {
        $file = "/var/run/radattr.{$param1}";
        $radattr = file_get_contents($file);
        $radattr = str_replace("\n", "<br>\n", $radattr);
        return $radattr;
    }

    public function radius() {
        $action = $_REQUEST["action"];
        $param1 = $_REQUEST["param1"];
        $param2 = $_REQUEST["param2"];
        switch ($action) {
            case "view":
                $out = $this->radius_view($param1, $param2);
                return $out;
                break;
            default:
        }
        $table = $this->sessions_to_array("action=view");
        $header[] = array("interface", "username", "calling id", "remote ip", "rate limit", "type", "comp", "state", "uptime");
        $table_html = rows2table(array_merge($header, $table), true);
        return $table_html;
    }

    public function bandwidth() {
        $bwm = file_get_contents("dumps/bwm.html");
        return $bwm;
    }

}

?>